#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

const char *root = "/";
const char *dev_null = "/dev/null";
void Daemon(bool ischdir, bool isclose)
{
    // 1. 忽略可能引起程序异常退出的信号
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);

    int rid = fork(); // 2.创建子进程
    if (rid > 0)
    {
        exit(1); // 父进程直接退出
    }

    int id = setsid(); // 3.子进程调用，子进程独立成立一个会话

    // 4. 每一个进程都有自己的 CWD， 是否将当前进程的 CWD 更改成为 /根目录
    // 以避免守护进程因当前工作目录被卸载而导致问题
    if (ischdir)
        chdir(root);

    // 5. 已经变成守护进程啦，不需要和用户的输入输出，错误进行关联了
    if (isclose)
    {
        close(0);
        close(1);
        close(2);
    }
    else
    {
        // 避免后面有向0，1，2中操作的，为了防止失败
        // 一般将0、1、2重定向到“黑洞”（任何写入到 /dev/null 的数据都会被永久丢弃，不会保存在任何地方）
        int fd = open(dev_null, O_RDWR);
        if (fd > 0)
        {
            dup2(fd, 0);
            dup2(fd, 1);
            dup2(fd, 2);
            close(fd); // 避免fd泄漏，重定向后关闭
        }
    }
}

// // ./server port
// int main(int argc, char *argv[])
// {
//     if (argc != 2)
//     {
//         std::cout << "Usage : " << argv[0] << " port" << std::endl;
//         return 0;
//     }
//     uint16_t localport = std::stoi(argv[1]);
//     Daemon(false, false);
//     std::unique_ptr<TcpServer> svr(new TcpServer(localport,HandlerRequest));
//     svr->Loop();
//     return 0;
// }